home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / gnu / gnu_oleo_1_2_2.lha / oleo-1.2.2 / string.c < prev    next >
C/C++ Source or Header  |  1993-03-03  |  7KB  |  354 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ctype.h>
  20. #include "funcdef.h"
  21. #define obstack_chunk_alloc ck_malloc
  22. #define obstack_chunk_free free
  23. #include "obstack.h"
  24. #include "sysdef.h"
  25.  
  26. #include "global.h"
  27. #include "cell.h"
  28. #include "eval.h"
  29. #include "errors.h"
  30.  
  31. struct value {
  32.     int    type;
  33.     union vals x;
  34. };
  35.  
  36. #define Float    x.c_d
  37. #define String    x.c_s
  38. #define Int    x.c_l
  39. #define Value    x.c_i
  40. #define Rng    x.c_r
  41.  
  42. #define ERROR(x)    \
  43.  {            \
  44.     p->Value=x;    \
  45.     p->type=TYP_ERR;\
  46.     return;        \
  47.  }
  48.     
  49.  
  50. extern struct obstack tmp_mem;
  51.  
  52. extern char *flt_to_str();
  53.  
  54. static void
  55. do_edit (numarg,p)
  56.      int numarg;
  57.       struct value * p;
  58. {
  59.     int mm;
  60.     int add_len;
  61.     int tmp_len;
  62.     char *ptr1,*ptr2,*retp;
  63.     int off1,off2;
  64.  
  65.     if(numarg<3)
  66.         ERROR(BAD_INPUT);
  67.     for(mm=3,add_len=0;mm<numarg;mm++)
  68.         add_len+=strlen((p+mm)->String);
  69.     tmp_len=strlen(p->String);
  70.     off1=(p+1)->Int;
  71.     off2=(p+2)->Int;
  72.     if(off1==0 || tmp_len < ((off1<0) ? -off1 : off1) ||
  73.        off2==0 || tmp_len < ((off2<0) ? -off2 : off2))
  74.         ERROR(OUT_OF_RANGE);
  75.     ptr1=p->String + (off1>0 ? off1-1 : tmp_len+off1);
  76.     ptr2=p->String + 1 + (off2>0 ? off2-1 : tmp_len+off2);
  77.     if(ptr1>ptr2)
  78.         ERROR(OUT_OF_RANGE);
  79.     retp=obstack_alloc(&tmp_mem,add_len+tmp_len-(ptr2-ptr1));
  80.     strncpy(retp,p->String,ptr1-p->String);
  81.     retp[ptr1-p->String]='\0';
  82.     for(mm=3;mm<numarg;mm++)
  83.         strcat(retp,(p+mm)->String);
  84.     strcat(retp,ptr2);
  85.     p->String=retp;
  86.     p->type=TYP_STR;
  87. }
  88.  
  89. static void
  90. do_repeat (p)
  91.      struct value * p;
  92. {
  93.     char *str = (p  )->String;
  94.     long num  = (p+1)->Int;
  95.  
  96.     char *ret;
  97.     char *strptr;
  98.     int len;
  99.  
  100.     if(num<0)
  101.         ERROR(OUT_OF_RANGE);
  102.     len=strlen(str);
  103.     ret=strptr=obstack_alloc(&tmp_mem,len*num+1);
  104.     while(num--) {
  105.         bcopy(str,strptr,len);
  106.         strptr+=len;
  107.     }
  108.     *strptr=0;
  109.     p->String=ret;
  110. }
  111.  
  112. static void
  113. do_len (p)
  114.      struct value * p;
  115. {
  116.     long ret;
  117.     char *ptr;
  118.  
  119.     for(ret=0,ptr=p->String;*ptr;ret++,ptr++)
  120.         ;
  121.     p->Int=ret;
  122.     p->type=TYP_INT;
  123. }
  124.  
  125. static void
  126. do_up_str (p)
  127.      struct value * p;
  128. {
  129.     char *s1,*s2;
  130.     char *strptr;
  131.  
  132.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  133.     for(s1=strptr,s2=p->String;*s2;s2++)
  134.         *s1++ = (islower(*s2) ? toupper(*s2) : *s2);
  135.     *s1=0;
  136.     p->String=strptr;
  137. }
  138.  
  139. static void
  140. do_dn_str (p)
  141.      struct value * p;
  142. {
  143.     char *s1,*s2;
  144.     char *strptr;
  145.  
  146.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  147.     for(s1=strptr,s2=p->String;*s2;s2++)
  148.         *s1++ = (isupper(*s2) ? tolower(*s2) : *s2);
  149.     *s1=0;
  150.     p->String=strptr;
  151. }
  152.  
  153. static void
  154. do_cp_str (p)
  155.      struct value * p;
  156. {
  157.     char *strptr;
  158.     char *s1,*s2;
  159.     int wstart=1;
  160.  
  161.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  162.     for(s1=strptr,s2=p->String;*s2;s2++) {
  163.         if(!isalpha(*s2)) {
  164.             wstart=1;
  165.             *s1++= *s2;
  166.         } else if(wstart) {
  167.             *s1++ = (islower(*s2) ? toupper(*s2) : *s2);
  168.             wstart=0;
  169.         } else
  170.             *s1++ = (isupper(*s2) ? tolower(*s2) : *s2);
  171.     }
  172.     *s1=0;
  173.     p->String=strptr;
  174. }
  175.  
  176. static void
  177. do_trim_str (p)
  178.      struct value * p;
  179. {
  180.     char *s1,*s2;
  181.     int sstart=0;
  182.     char *strptr;
  183.  
  184.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  185.     for(s1=strptr,s2=p->String;*s2;s2++) {
  186.         if(!isascii(*s2) || !isprint(*s2))
  187.             continue;
  188.         if(*s2==' ') {
  189.                 if(sstart) {
  190.                 *s1++= *s2;
  191.                 sstart=0;
  192.             }
  193.         } else {
  194.             sstart=1;
  195.             *s1++= *s2;
  196.         }
  197.     }
  198.     *s1=0;
  199.     p->String=strptr;
  200. }
  201.  
  202. static void
  203. do_concat ( numarg,p)
  204.      int  numarg;
  205.       struct value * p;
  206. {
  207.     int cur_string;
  208.     char *s;
  209.     char buf[40];
  210.     CELLREF crow,ccol;
  211.     CELL *cell_ptr;
  212.  
  213.     for(cur_string=0;cur_string<numarg;cur_string++) {
  214.         switch(p[cur_string].type) {
  215.         case 0:
  216.             continue;
  217.         case TYP_RNG:
  218.             for(crow=p[cur_string].Rng.lr;crow<=p[cur_string].Rng.hr;crow++)
  219.                 for(ccol=p[cur_string].Rng.lc;ccol<=p[cur_string].Rng.hc;ccol++) {
  220.                     if(!(cell_ptr=find_cell(crow,ccol)))
  221.                         continue;
  222.                     switch(GET_TYP(cell_ptr)) {
  223.                     case 0:
  224.                         break;
  225.                     case TYP_STR:
  226.                         (void)obstack_grow(&tmp_mem,cell_ptr->cell_str,strlen(cell_ptr->cell_str));
  227.                         break;
  228.                     case TYP_INT:
  229.                         sprintf(buf,"%ld",cell_ptr->cell_int);
  230.                         (void)obstack_grow(&tmp_mem,buf,strlen(buf));
  231.                         break;
  232.                     case TYP_FLT:
  233.                         s=flt_to_str(cell_ptr->cell_flt);
  234.                         (void)obstack_grow(&tmp_mem,s,strlen(s));
  235.                         break;
  236.                     default:
  237.                         (void)obstack_finish(&tmp_mem);
  238.                         ERROR(NON_STRING);
  239.                     }
  240.             }
  241.             break;
  242.         case TYP_STR:
  243.             s=p[cur_string].String;
  244.             (void)obstack_grow(&tmp_mem,s,strlen(s));
  245.             break;
  246.         case TYP_INT:
  247.             sprintf(buf,"%ld",p[cur_string].Int);
  248.             (void)obstack_grow(&tmp_mem,buf,strlen(buf));
  249.             break;
  250.         case TYP_FLT:
  251.             s=flt_to_str(p[cur_string].Float);
  252.             (void)obstack_grow(&tmp_mem,s,strlen(s));
  253.             break;
  254.         default:
  255.             (void)obstack_finish(&tmp_mem);
  256.             ERROR(NON_STRING);
  257.         }
  258.     }
  259.     (void)obstack_1grow(&tmp_mem,0);
  260.     p->type=TYP_STR;
  261.     p->String=(char *)obstack_finish(&tmp_mem);
  262. }
  263.  
  264.  
  265. static void
  266. do_mid (p)
  267.      struct value * p;
  268. {
  269.     char *str = (p  )->String;
  270.     long from = (p+1)->Int;
  271.     long len =  (p+2)->Int;
  272.  
  273.     char    *ptr1;
  274.     int tmp;
  275.  
  276.     tmp=strlen(str);
  277.  
  278.     if(from<0 || len<0)
  279.         ERROR(OUT_OF_RANGE);
  280.     ptr1=(char *)obstack_alloc(&tmp_mem,len+1);
  281.     if(from>=tmp || len==0)
  282.         ptr1[0]='\0';
  283.     else {
  284.         strncpy(ptr1,str+from,len);
  285.         ptr1[len]='\0';
  286.     }
  287.     p->String=ptr1;
  288. }
  289.  
  290.  
  291. static void
  292. do_substr (p)
  293.      struct value * p;
  294. {
  295.     long off1 = (p  )->Int;
  296.     long off2 = (p+1)->Int;
  297.     char *str = (p+2)->String;
  298.  
  299.     char    *ptr1,    *ptr2;
  300.     int tmp;
  301.     char *ret;
  302.  
  303.     tmp=strlen(str);
  304.     if(off1==0 || tmp < ((off1<0) ? -off1 : off1) ||
  305.        off2==0 || tmp < ((off2<0) ? -off2 : off2))
  306.         ERROR(OUT_OF_RANGE);
  307.     ptr1=str + (off1>0 ? off1-1 : tmp+(off1));
  308.     ptr2=str + (off2>0 ? off2-1 : tmp+(off2));
  309.  
  310.     if(ptr1>ptr2)
  311.         ERROR(OUT_OF_RANGE);
  312.     tmp=(ptr2-ptr1)+1;
  313.     ret=(char *)obstack_alloc(&tmp_mem,tmp+1);
  314.     strncpy(ret,ptr1,tmp);
  315.     ret[tmp]=0;
  316.     p->String=ret;
  317.     p->type=TYP_STR;
  318. }
  319.  
  320. static void
  321. do_strstr (p)
  322.      struct value * p;
  323. {
  324.     char *str1    = (p  )->String;
  325.     char *strptr    = (p+1)->String;
  326.     long off    = (p+2)->Int;
  327.     char *ret;
  328.  
  329.     if(off<1 || strlen(strptr)<=off-1)
  330.         ERROR(OUT_OF_RANGE);
  331.     ret=(char *)strstr(strptr+off-1,str1);
  332.     p->Value= ret ? 1 + ret-strptr : 0;
  333.     p->type=TYP_INT;
  334. }
  335.  
  336. struct function string_funs[] = {
  337. { C_FN1,    X_A1,    "S",    do_len,        "len" },
  338. { C_FN3,    X_A3,    "SSI",  do_strstr,    "find" },
  339.  
  340. { C_FN1,    X_A1,    "S",    do_up_str,    "strupr" },
  341. { C_FN1,    X_A1,    "S",    do_dn_str,    "strlwr" },
  342. { C_FN1,    X_A1,    "S",    do_cp_str,    "strcap" },
  343. { C_FN1,    X_A1,    "S",    do_trim_str,    "trim" },
  344.  
  345. { C_FN3,    X_A3,    "IIS",  do_substr,    "substr" },
  346. { C_FN3,    X_A3,    "SII",  do_mid,        "mid" },
  347.  
  348. { C_FN2,    X_A2,    "SI",   do_repeat,    "repeat" },
  349. { C_FNN,    X_AN,    "EEEE", do_concat,    "concat" },
  350. { C_FNN,    X_AN,    "SIIS", do_edit,    "edit" },
  351. { 0,        0,    0,    0,        0 },
  352. };
  353.  
  354.